/**
 * Copyright (c) 2011-2016, James Zhan 詹波 (jfinal@126.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.candy.db.generator.core;


import com.candy.db.generator.config.GlobalConfig;
import com.candy.db.generator.utils.*;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Model 生成器
 */
public class ModelGenerator {
	protected String modelPackageName;
    protected  String baseModelPackageName;
	protected String modelOutputDir;

	public ModelGenerator(String baseModelPackageName,String modelPackageName, String modelOutputDir) {
		if (StrKit.isBlank(modelPackageName))
			throw new IllegalArgumentException("modelPackageName can not be blank.");
		if (modelPackageName.contains("/") || modelPackageName.contains("\\"))
			throw new IllegalArgumentException("modelPackageName error : " + modelPackageName);
		if (StrKit.isBlank(modelOutputDir))
			throw new IllegalArgumentException("modelOutputDir can not be blank.");

        this.baseModelPackageName = baseModelPackageName;
		this.modelPackageName = modelPackageName;
		this.modelOutputDir = modelOutputDir;
	}
	

	public void generate(List<TableMeta> tableMetas) {
		System.out.println("Generate model ...");
		for (TableMeta tableMeta : tableMetas)
        {
            genModelContent(tableMeta);
        }
	}
	
	protected void genModelContent(TableMeta tableMeta) {
        File file = new File(modelOutputDir+File.separator+tableMeta.modelName+ GlobalConfig.exportFileSuffix);
        if(file.exists() && !GlobalConfig.overrideForce){
            LogKit.debug("file :"+ file.getAbsolutePath()+" exist! Ignore  it ...");
            return;
        }
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }

        Map rootMap = BeanToMap.Bean2Map(tableMeta);
        rootMap.put("modelPackageName",modelPackageName);
        rootMap.put("baseModelPackageName",baseModelPackageName);
        rootMap.put("author",GlobalConfig.classAuthor);

        FreeMarkerKit.make(rootMap,"model.ftl",file.getAbsolutePath());
	}

    public static void main(String[] args) {
        FileWriter writer = null;
        try {
            Configuration cfg = new Configuration();
//            cfg.setDirectoryForTemplateLoading(new File("resources"));

            Template template = cfg.getTemplate("model.ftl");

            Map<String, String> root = new HashMap<String, String>();
            root.put("name", "cxl");
            root.put("age", "25");

            writer = new FileWriter("c:/test/test.java");
            template.process(root, writer);
            writer.flush();
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            IOUtils.closeQuietly(writer);
        }
    }

    protected void wirtToFile(List<TableMeta> tableMetas) {
		try {
			for (TableMeta tableMeta : tableMetas)
				wirtToFile(tableMeta);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 若 model 文件存在，则不生成，以免覆盖用户手写的代码
	 */
	protected void wirtToFile(TableMeta tableMeta) throws IOException {
		File dir = new File(modelOutputDir);
		if (!dir.exists())
			dir.mkdirs();
		
		String target = modelOutputDir + File.separator + tableMeta.modelName + ".java";
		
		File file = new File(target);
		if (file.exists()) {
			return ;	// 若 Model 存在，不覆盖
		}
		
		FileWriter fw = new FileWriter(file);
		try {
			fw.write(tableMeta.modelContent);
		}
		finally {
			fw.close();
		}
	}
}


